import { BaseConnection, WsClient, WsClientStatus } from "tsrpc";
import { logger } from "../../server/logger";
import { baseBody } from "./baseBody";
import { ServiceType } from "../../../shared/master/serviceProto";
import { Tpl_attribute, Tpl_gifts_default, template } from "../../../shared/master/MsgAction";
import battlefield from "../battle/battlefield";
import { bag } from "../../bag/bag";
import { equip } from "../equip/equip";
import { bar, mail_item, prop_min_type, rank_type, taskKey, transactionLog } from "../../../shared/interface";
import app, { xlsxCfgNames } from "../../../app";
import { SKILL, battle_log, battle_logNum } from "../skill/SK_active";
import { prop_base } from "../../bag/prop_base";
import { wordTask } from "../../../master/model/task/wordTask";
import master from "../../../master";
import { _Cls_Points } from "./att/_Points";
import { _Cls_Att } from "./att/_Att";
import { pet } from "./pet";
import { CreateBody_calls } from "./calls";
import body_tool from "./body_tool";
import god from "../../../god";
import manage_user from "../../../master/model/manage/manage_user";
import { team } from "../../../master/model/lib/team";
import manage_team from "../../../master/model/manage/manage_team";
import manage_word from "../../../master/model/manage/manage_word";
import { user_log } from "./att/_log";
import { EntrustTask } from "../../../master/model/task/EntrustTask";
import { EverdayTask } from "../../../master/model/task/EverdayTask";
import { NewbieTask } from "../../../master/model/task/NewbieTask";
import manage_task from "../../../master/model/manage/manage_task";
import { EverweekTask } from "../../../master/model/task/EverweekTask";

export enum wallet_key {
    /**
     * 金币
     */
    gold,
    /**
     * 点券
     */
    diamond
}
export class player extends baseBody {
    icon: string = '🧙';
    // team_id: string = '666';
    _LastLocation: string = '';
    /**
     * 钱包
     * 
     */
    wallet: number[] = []
    private _conn: BaseConnection<any> | undefined;
    private enterCopyGameDownTime: number = Date.now() + 1000;
    private enterCopyGameDownTimeLastSendTime = Date.now();
    private _bag_lastFilter: prop_min_type | undefined;
    private bag: bag = new bag();
    private _wordTask?: wordTask;
    private _mailChckTime: number = 0;
    private entrustTask: EntrustTask | undefined;
    private everdayTask: EverdayTask | undefined;
    private everweekTask: EverdayTask | undefined;
    private newbieTask: NewbieTask | undefined;
    /**
     * 等级锁 等级
     */
    private DNA_leve = 0;
    /**
     * 砍树等级
     */
    leve_chopping: bar = {
        num: 1,
        now: 0,
        max: 100
    }
    /**
     * 钓鱼等级
     */
    leve_fishing:bar = {
        num: 1,
        now: 0,
        max: 100
    }
    mail: mail_item[] = []
    mail_serverDev: number = 0;
    log!: user_log;
    // 称号
    title_style: string = '1';
    title_value: _Cls_Att = new _Cls_Att();
    team_id: string = '';
    private _team: team | undefined;
    constructor() {
        super();
        this.setBodyType('player')
        this.log = new user_log(undefined,this)
    }
    addExp_chopping(num: number) {
        app.leveAddExp(num, this.leve_chopping, this.upLeve_chopping);
    }
    addExp_fishing(num: number) {
        app.leveAddExp(num, this.leve_fishing, this.upLeve_fishing);
    }
    private upLeve_chopping = () =>  {
        this.leve_chopping.num += 1;
        this.leve_chopping.max = app.random(this.leve_chopping.num * 100, this.leve_chopping.num * 200);
        return true;
    }
    private upLeve_fishing = () =>  {
        this.leve_fishing.num += 1;
        this.leve_fishing.max = app.random(this.leve_fishing.num * 100, this.leve_fishing.num * 200);
        return true;
    }
    get_DNA_Lv() {
        return this.DNA_leve;
    }
    rankLog(key: rank_type, num: number, name = this.name) {
        god.rank_tick({
            uuid: this.uuid,
            name: name,
            type: key,
            num: num,
            style: this.style_id,
            title_style: this.title_style
        })
    }
    get_entrustTask() {
        if (!this.entrustTask) {
            this.entrustTask = new EntrustTask();
            this.entrustTask.update(this)
        }
        return this.entrustTask;
    }
    get_everdayTask() {
        if (!this.everdayTask) {
            this.everdayTask = new EverdayTask();
            this.everdayTask.update(this);
        }
        return this.everdayTask;
    }
    get_everweekTask() {
        if (!this.everweekTask) {
            this.everweekTask = new EverweekTask();
            this.everweekTask.update(this);
        }
        return this.everweekTask;
    }
    get_newbieTask() {
        if (!this.newbieTask && this.log.newBie_endTime == 0) {
            this.newbieTask = new NewbieTask().update(this)
        }
        return this.newbieTask;
    }
    async save() {
        manage_user.save(this);
        // let obj = app.sanitizeObject(this);
        // // debugger;
        // await db.set(dbKey.player, this.uuid, obj)
    }
    set_Cfg(data: CreateBody_calls) {

    }
    upLeve_dna() {
        // this.DNA_leve += 1;
        // let nowInfo = god.getDNA_info(this.DNA_leve)
        // this.rankLog(rank_type.基因锁等级, this.DNA_leve)
        // this.sendMsg(template.default, `恭喜你！基因锁已解锁至:${nowInfo.name}`)
        // manage_user.sendAllMsg(template.default, `恭喜${this.name}!基因锁已解锁至:${nowInfo.name}`)
    }
    get_panel_talent() {
        let data = super.get_panel_talent();
        data.title_style = this.title_style;
        return data;
    }
    reset_talent(id?: string) {
        let add = this.get_DNA_Lv()
        let score = super.reset_talent(id, add) * 100

        this.rankLog(rank_type.天赋资质, score)

        return score
    }
    update_attributes(): void {
        super.update_attributes();
        this._attributes.setMultiple_data(this.title_value, 100)
    }
    get_team() {
        return this._team
    }
    update_team() {
        let _team = manage_team.getTeam(this)
        if (_team) {
            let info = _team.getMember(this.uuid)
            if (info) {
                this._team = _team;
            }
        }
    }
    get_panel_job() {
        let data = super.get_panel_job();
        data.title_style = this.title_style;
        return data;
    }
    addExp(num: number) {
        let lastLeve = this.leve.num;
        super.addExp(num)
        let _team = this.get_team();
        if (_team) {
            _team.addExp(this, num)
        }
        if (lastLeve != this.leve.num) {
            this.rankLog(rank_type.等级, this.leve.num)
        }
    }
    private getLeveLock() {
        let baseLeve = 1000;
        let maxLeve = this.DNA_leve * baseLeve + baseLeve;
        return maxLeve
    }
    upLeve = () => {
        if (this.leve.num >= this.getLeveLock()) {
            this.leve.now = 0;
            return false;
        }
        this.leve.num += 1;
        this.leve.max = this.leve.num * god.getServerCfgItem('leve_exp_base').b;
        return true
    }
    reload(data: player) {
        console.time('reload')
        let _data: any = data;
        const jumpKey = ['P', 'skills_body', 'equip_ordinary', 'pets', 'bag', 'Talent', 'Job', 'log', 'entrustTask', 'everdayTask', 'newbieTask']
        for (const key in data) {
            if (key.startsWith('_')) {
                continue;
            }
            if (jumpKey.includes(key)) {
                continue;
            }
            this[key] = _data[key]
        }


        for (let i = 0; i < data.skills_body.length; i++) {
            let sk = new SKILL(_data.skills_body[i])
            this.skills_body.push(sk)
        }
        for (let i = 0; i < data.equip_ordinary.length; i++) {
            if (!data.equip_ordinary[i]) {
                this.equip_ordinary.push(undefined);
                continue;
            }
            let e = new equip();
            const rdata = _data.equip_ordinary[i]
            e.reload(rdata)
            this.equip_ordinary.push(e)
        }
        for (let i = 0; i < data.pets.length; i++) {
            const element = data.pets[i];
            const p = new pet()
            p.reload(element);
            this.addPet(p);
        }
        if (data.entrustTask) {
            this.entrustTask = new EntrustTask().reload(data.entrustTask)
        }
        // 每日任务初始化
        this.everdayTask = new EverdayTask().reload(data.everdayTask);
        if (!app.isSameDay(this.everdayTask.createTime, Date.now())) {
            this.everdayTask.update(this);
        }
        this.everweekTask = new EverweekTask().reload(data.everweekTask);
        if (!app.isSameWeek(this.everweekTask.createTime, Date.now())) {
            this.everweekTask.update(this);
        }
        this.log = new user_log(data.log,this)
        if (this.log.newBie_endTime == 0) {
            this.newbieTask = new NewbieTask().reload(data.newbieTask)
            if (!data.newbieTask) {
                this.newbieTask.update(this);
            }
        }

        this.bag.reload(data.bag)
        this.P.reset(data.P);
        this.Talent.reset(data.Talent)
        this.Job.reset(data.Job);
        this.update_team();
        console.timeEnd('reload')
        this.init();
    }
    getPosition() {
        let cell = super.getPosition();
        if (!cell) {
            // this.sendMsg(template.default, `检测到位置异常请[挂机]下线后重新登录.`)
            manage_word.transfer(this, '1');
            return super.getPosition()
        }
        return cell;
    }
    onLine() {
        let offline = Math.floor((Date.now() - this._lastActiveTime) / 1000);
        if (offline < 120) {
            return;
        }
        let useCont = Math.floor(offline / 60);
        let item = this.getBag().getItem_cfgId('prop-21');
        if (useCont == 0) {
            this.sendMsg(template.default, `挂机时长不足1分钟,本次挂机没有奖励噢`)
            return;
        }
        if (!item) {
            this.sendMsg(template.default, `由于没有🐟️小鱼干,本次挂机没有奖励噢`)
            return;
        }
        if (useCont > item.num) {
            useCont = item.num;
        }
        let res = this.check_wallet(0, 0, [{ id: 'prop-21', v: useCont }], false, `挂机消耗`, false);
        if (!res.state) {
            return;
        }
        // let offline_max = 86400 * 5;
        // if (offline > offline_max) {
        //     offline = offline_max
        // }

        manage_task.event(taskKey.挂机时长, Math.floor(useCont), this)
        this.log.add(rank_type.挂机时长, useCont)
        let items = god.getRandomItems(useCont * 0.03, '挂机获得', xlsxCfgNames.挂机配置)
        let exp = useCont * 100
        this.addExp(exp)
        let list = this.addItems(items);
        list.push({ name: item.getStyleName(), num: -useCont })
        list.push({ name: '⏳经验', num: exp })
        let tpl: Tpl_gifts_default = {
            title: `挂机奖励:`,
            items: list
        }
        this.sendMsg(template.通用奖励, tpl)
    }
    addItems(list: prop_base[]) {
        let resList: { name: string, num: number }[] = []
        for (let i = 0; i < list.length; i++) {
            const element = list[i];
            if (!element) {
                continue;
            }
            this.getBag().add(element)
            resList.push({ name: element.getStyleName(), num: element.num })
        }
        return resList;
    }
    active(): void {
        super.active();
        // 检查玩家世界boss 是否出现
        try {
            this.getPosition()?.getWord()?.bossCls.check();
        } catch (error) {

        }
        // 检查是否有邮件
        const cfg = god.getServerCfgItem('mail_remind')
        if (this.mail.length > 0 && Date.now() - this._mailChckTime > Number(cfg.a)) {
            this._mailChckTime = Date.now();
            this.sendMsg(template.default, `你有${this.mail.length}条邮件,查看发送[阅读]`)
        }
        this.get_team()?.tick(this)
    }
    setWordTask(t: wordTask | undefined) {
        if (this._wordTask) {
            this._wordTask.destroy();
            this._wordTask = undefined;
        }
        this._wordTask = t;
        if (t) {
            let word = this.getPosition().getWord();
            t.notice(word.cfg.wordDesc);
        }
    }
    async callApi<T extends string & keyof ServiceType['api']>(apiName: T, req: ServiceType['api'][T]['req']) {
        // ${call.req._platform}_${call.req._onlyid}
        let infoArry = this.uuid.split('_')
        let _platform = infoArry[0];
        let _onlyid = infoArry[1]
        return master.s_wss.callApi(apiName, {
            ...req,
            _platform: _platform,
            _onlyid: _onlyid,
            _fromid: this._LastLocation
        })
    }
    _callApi(key: string, req: any) {
        let infoArry = this.uuid.split('_')
        let _platform = infoArry[0];
        let _onlyid = infoArry[1]
        master.s_wss.callApi(key, {
            ...req,
            _platform: _platform,
            _onlyid: _onlyid,
            _fromid: this._LastLocation
        })
    }
    getWordTask() {
        return this._wordTask;
    }
    refBagLastFilter(t: any) {
        this._bag_lastFilter = t;
    }
    getBagLastFilter() {
        return this._bag_lastFilter;
    }
    getMsgAttTpl() {
        this.update_attributes();
        let cfg = app.xlsxCfgMap.get(xlsxCfgNames.天赋表)?.get(this.Talent_id) as any;
        let score = this.getScore();
        this.rankLog(rank_type.天赋等级, this.Job_leve.num)
        this.rankLog(rank_type.等级, this.leve.num)
        this.rankLog(rank_type.血统等级, this.Talent_leve.num)
        this.rankLog(rank_type.战力, score)
        this.rankLog(rank_type.物攻, this._attributes.Physical_Attack_max)
        this.rankLog(rank_type.物防, this._attributes.Physical_defense)
        this.rankLog(rank_type.魔防, this._attributes.Magic_defense)
        this.rankLog(rank_type.魔攻, this._attributes.Magic_Attack_max)
        this.rankLog(rank_type.生命, this._attributes.Hp_Max)


        let _team = this.get_team();
        let _teamName = _team ? _team.name : '暂无小队';
        let _teamInfo = _team?.getMember(this.uuid);
        if (_teamInfo) {
            if (_teamInfo.leve == 1) {
                _teamName += `·队长`
            } else {
                _teamName += `·成员`
            }
        }
        let dna_info = god.getDNA_info(this.DNA_leve)
        let tpl: Tpl_attribute = {
            title_style: this.title_style,
            render_type: 'player_concise',
            dna_name: dna_info.name,
            job_name: this.get_job_cfg().name,
            team_name: _teamName,
            name: this.name,
            body_type: this._bodyType,
            style_id: this.style_id,
            hp_now: this.Hp_now,
            mp_now: this.Mp_now,
            leve: this.leve,
            Talent_name: cfg.name,
            Points: this.get_panelPoints(),
            attributes: this._attributes,
            score: score,
        }
        return { template: template.attribute, data: tpl };
    }
    checkEnterCopyGameSend() {
        if (this.enterCopyGameDownTimeLastSendTime < Date.now()) {
            this.enterCopyGameDownTimeLastSendTime = Date.now() + 10000
            return true;
        }
        return false;
    }
    /**
     * 读取进入轮回世界倒计时时间
     */
    checkEnterCopyGame() {
        if (this.getPosition().getWord().id != '1') {
            return false;
        }

        return this.enterCopyGameDownTime < Date.now();
    }
    wear_equip(data: equip) {
        let use = false;
        let equip_cell: (equip | undefined)[] = this.equip_ordinary
        if (equip_cell.length >= 6) {
            for (let i = 0; i < equip_cell.length; i++) {
                const element = equip_cell[i];
                if (!element) {
                    equip_cell[i] = data;
                    use = true;
                    break;
                }
            }
        } else {
            equip_cell.push(data)
            use = true;
        }
        return use;
    }
    /**
     * 输入一个index
     */
    remove_equip(idx: number) {
        let equip_cell: (equip | undefined)[] = []
        equip_cell = this.equip_ordinary;
        let bag = this.getBag();
        let unequip = equip_cell[idx];
        if (!unequip) {
            return false;
        }
        let equip_item = app.createItem({
            min_type: prop_min_type.装备,
            num: 1,
            score: unequip.score,
            from: unequip.from,
            data: unequip
        })
        bag.add(equip_item);
        equip_cell[idx] = undefined;
        this.update_attributes();
        bag.sort();
        return true;
    }
    getBag() {
        return this.bag;
    }
    getBagList() {
        let lastFilter = this.getBagLastFilter();
        let bag = this.getBag();
        let resArry: (prop_base | undefined)[] = [];
        for (let index = 0; index < bag.items.length; index++) {
            const element = bag.items[index];
            if (!element) {
                resArry.push(undefined);
            } else {
                if (typeof (lastFilter) == 'undefined' || lastFilter == element.min_type) {
                    if (element.num <= 0) {
                        resArry.push(undefined);
                        continue;
                    }
                    resArry.push(element);
                }
            }
        }
        return resArry;
    }
    wallet_change(key: wallet_key, num: number) {
        if (typeof (this.wallet[key]) == 'undefined') {
            this.wallet[key] = 0;
        }
        this.wallet[key] += Math.ceil(num);
        this.wallet[key] = Math.ceil(this.wallet[key]);
        switch (key) {
            case wallet_key.gold:
                this.rankLog(rank_type.金币, this.wallet[key])
                break;

            default:
                break;
        }
    }
    wallet_get(key: wallet_key) {
        if (typeof (this.wallet[key]) == 'undefined') {
            this.wallet[key] = 0;
        }
        return this.wallet[key]
    }
    /**
     * 记录最后一次活跃的聊天位置
     */
    setLastLocation(id: string) {
        this._LastLocation = id;
    }
    async sendMsg(tel: template | string, data?) {
        let conn = this.getConn() as unknown as WsClient<ServiceType>;
        if (!conn || conn.status != 'OPENED') {
            logger.error('用户没有连接端');
            return;
        }


        let jude = await conn.sendMsg('Action', {
            template: tel,
            tolocation: this._LastLocation,
            data: data
        });
    }
    setConn(conn) {
        this._conn = conn;
    }
    getConn() {
        return this._conn
    }
    on_battleSelect() {
        // this.sendMsg(template.default, '新的回合开始! 请选择使用的技能或魔法引导咒[倒计时30s]')
        // setTimeout(() => {
        //     this.set_hasDecided(area.round);
        //     area.on_battleSelect(this);
        // }, 15000)
    }
    /**
    * 复活
    */
    res_life(log: battle_logNum) {
        super.res_life(log)

    }
    add_hp(log: battle_logNum, send?) {
        body_tool.add_hp(this, log)
        if (send) {
            let change = log.val > 0 ?'+':''
            this.sendMsg(template.default, `HP${change}${log.val.toFixed(2)} 来源:${log.use_name}[${log.sk_name}]`);
        }
    }
    add_mp(log: battle_logNum, send?) {
        body_tool.add_mp(this, log)
        if (send) {
            let change = log.val > 0 ?'+':''
            this.sendMsg(template.default, `MP${change}${log.val.toFixed(2)}MP 来源:${log.use_name}[${log.sk_name}]`);
        }
    }
    /**
     * @param gold 
     * @param diamond 
     * @param items 
     * @param check 如果是发生实际交易 则为ture
     * @param reason 交易原因
     * @param send 是否发出此次执行结果
     * @returns 
     */
    check_wallet(gold: number, diamond: number, items: { id: string, v: number }[], check: boolean, reason: string, send?: boolean) {
        let jude = true;
        let log: transactionLog = {
            createTime: Date.now(),
            state: false,
            gold: {
                need: gold,
                now: this.wallet_get(wallet_key.gold)
            },
            diamond: {
                need: diamond,
                now: this.wallet_get(wallet_key.diamond)
            },
            items: [],
            reason: reason
        }
        if (this.wallet_get(wallet_key.gold) < gold) {
            jude = false;
        }
        if (this.wallet_get(wallet_key.diamond) < diamond) {
            jude = false;
        }
        let itemsC: prop_base[] = []
        for (let i = 0; i < items.length; i++) {
            const element = items[i];
            let item: prop_base;
            if (element.id.includes('-')) {
                // 查找指定道具
                item = this.getBag().getItem_cfgId(element.id);
                itemsC.push(item)
                if (!item) {
                    jude = false;
                    log.items.push({ name: app.getCfgPropTypeName(element.id), need: element.v, now: 0 })
                    continue;
                }
            } else {
                // 范围查找道具
                item = this.getBag().getItem_cfgType(element.id);
                itemsC.push(item)
                if (!item) {
                    jude = false;
                    log.items.push({ name: app.getCfgPropTypeName(element.id), need: element.v, now: 0 })
                    continue;
                }
            }
            if (item.num < element.v) {
                jude = false;
            }
            log.items.push({ name: item.getStyleName(), need: element.v, now: item.num })
        }
        if (jude) {
            log.state = true;
        }
        if (jude && !check) {
            // 开始扣道具
            this.wallet_change(wallet_key.gold, -gold)
            this.wallet_change(wallet_key.diamond, -diamond)
            log.gold.now = this.wallet_get(wallet_key.gold)
            log.diamond.now = this.wallet_get(wallet_key.diamond)
            for (let i = 0; i < items.length; i++) {
                const element = items[i];
                itemsC[i].cont_change(-element.v)
                log.items[i].now = itemsC[i].num;
            }
        }
        if (send) {
            this.sendMsg(template.transactionLog, log)
        }
        return log;
    }

}